## Graphical front-end for polysat 1.0
## Written by Lindsay Clark with much inspiration from sciviews.org

require("polysat")
require("tcltk2")

# Basic objects needed for GUI
if(!"genobject" %in% ls()){
    genobject <- new("genambig") # A dummy dataset
}
if(!"gsamples" %in% ls()){
    gsamples <- list(All = Samples(genobject)) # A list of sample sets
}
if(!"csamples" %in% ls()){
    csamples <- "All" # the name of the current sample set
}
if(!"gloci" %in% ls()){
    gloci <- list(All = Loci(genobject)) # A list of locus sets
}
if(!"cloci" %in% ls()){
    cloci <- "All" # the name of the current locus set
}
uCount <- length(Loci(genobject)) # for gUsatnts
pCount <- length(PopNames(genobject)) # for gPopInfo

## Functions used by the GUI

# re-initialization for after new datasets are loaded
pginitialize <- function(){
    gsamples <<- list(All=Samples(genobject))
    csamples <<- "All"
    gloci <<- list(All=Loci(genobject))
    cloci <<- "All"
    uCount <<- length(Loci(genobject))
    pCount <<- length(PopNames(genobject))
}

# Pop up dialog to edit description
gDescription <- function(){
    editWin <- tktoplevel()
    tkwm.title(editWin, "Description")
    textEntryVarTcl <- tclVar(Description(genobject)[1])
    textEntryWidget <- tkentry(editWin, width=100,
                               textvariable = textEntryVarTcl)
    tkgrid(tklabel(editWin, text="Edit dataset description:"))
    tkgrid(textEntryWidget)

    onOK <- function(){
        Description(genobject) <<- tclvalue(textEntryVarTcl)
        tkdestroy(editWin)
    }
    onCancel <- function(){
        tkdestroy(editWin)
    }
    OKbutton <- tkbutton(editWin, text=" OK ", command=onOK)
    CancelButton <- tkbutton(editWin, text=" Cancel ", command=onCancel)
    tkgrid(OKbutton, CancelButton)
}

# Edit PopNames
gPopNames <- function(){
    pnframe <- data.frame(PopNames = PopNames(genobject),
                          stringsAsFactors=FALSE)
    PopNames(genobject) <<- as.character(edit(pnframe)[["PopNames"]])
    pCount <<- length(PopNames(genobject))
}

# Edit PopInfo
gPopInfo <- function(){
    # error prevention (shouldn't need):
    if(pCount > length(PopNames(genobject)))
        pCount <<- length(PopNames(genobject))
    # give error if there aren't populations yet
    if(pCount==0) stop("Define population names first.")
    # figure out which population this is (do a countdown; see buttons below)
    P <- PopNames(genobject)[length(PopNames(genobject))-pCount+1]

    # Set up a window with a listbox to select individuals for this pop
    popiWin <- tktoplevel()
    tkwm.title(popiWin, P)
    tkgrid(tklabel(popiWin, text=paste("Select individuals in",P,":")))
    scr <- tkscrollbar(popiWin, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
    tl <- tklistbox(popiWin, height=30, selectmode="extended",
                    yscrollcommand=function(...)tkset(scr,...),
                    background="white")
    tkgrid(tl, scr)
    tkgrid.configure(scr,rowspan=4,sticky="nsw")
    for(s in Samples(genobject)){
        tkinsert(tl,"end",s)
    }

    # Buttons: back, done, next
    onDone <- function(){
        PopInfo(genobject)[as.numeric(tkcurselection(tl))+1] <<-
            PopNum(genobject, P)
        pCount <<- length(PopNames(genobject))
        tkdestroy(popiWin)
    }
    onBack <- function(){
        tkdestroy(popiWin)
        pCount <<- pCount + 1
        gPopInfo()
    }
    onNext <- function(){
        PopInfo(genobject)[as.numeric(tkcurselection(tl))+1] <<-
            PopNum(genobject, P)
        pCount <<- pCount - 1
        tkdestroy(popiWin)
        gPopInfo()
    }
    doneBut <- tkbutton(popiWin, text=" Done ", command=onDone)
    backBut <- tkbutton(popiWin, text="<<Back", command=onBack)
    nextBut <- tkbutton(popiWin, text="Next>>", command = onNext)
    if(pCount==1) tkgrid(backBut, doneBut)
    if(pCount==length(PopNames(genobject))) tkgrid(doneBut, nextBut)
    if(pCount > 1 && pCount < length(PopNames(genobject)))
        tkgrid(backBut, doneBut, nextBut)
}

# Edit Usatnts
gUsatnts <- function(){
    # error prevention (shouldn't need):
    if(uCount > length(Loci(genobject))) uCount <<- length(Loci(genobject))
    # figure out which locus this is (do a countdown; see buttons below)
    L <- Loci(genobject)[length(Loci(genobject))-uCount+1]
    # set up window with radio buttons to select repeat type
    usatWin <- tktoplevel()
    tkwm.title(usatWin, L)
    tkgrid(tklabel(usatWin, text=paste("Locus", L, "is:")))
    rb1a <- tkradiobutton(usatWin)
    rb1 <- tkradiobutton(usatWin)
    rb2 <- tkradiobutton(usatWin)
    rb3 <- tkradiobutton(usatWin)
    rb4 <- tkradiobutton(usatWin)
    rb5 <- tkradiobutton(usatWin)
    rb5 <- tkradiobutton(usatWin)
    rb6 <- tkradiobutton(usatWin)
    # set up initial button to have selected - try to use previous selection
    if(is.na(Usatnts(genobject)[L])){
        rbTclVar <- tclVar(2) # dinucleotide if nothing there yet
    } else {
        rbTclVar <- tclVar(Usatnts(genobject)[L])
    }
    tkconfigure(rb1a, variable=rbTclVar, value=0)
    tkconfigure(rb1, variable=rbTclVar, value=1)
    tkconfigure(rb2, variable=rbTclVar, value=2)
    tkconfigure(rb3, variable=rbTclVar, value=3)
    tkconfigure(rb4, variable=rbTclVar, value=4)
    tkconfigure(rb5, variable=rbTclVar, value=5)
    tkconfigure(rb6, variable=rbTclVar, value=6)
    tkgrid(tklabel(usatWin,
                   text="Already expressed in terms of repeat number."),
           rb1a)
    tkgrid(tklabel(usatWin,
             text="Expressed as fragment length in nucleotides and is a:"))
    tkgrid(tklabel(usatWin, text="Mononucloeotide repeat."),rb1)
    tkgrid(tklabel(usatWin, text="Dinucleotide repeat."),rb2)
    tkgrid(tklabel(usatWin, text="Trinucleotide repeat."),rb3)
    tkgrid(tklabel(usatWin, text="Tetranucleotide repeat."),rb4)
    tkgrid(tklabel(usatWin, text="5 bp repeat."),rb5)
    tkgrid(tklabel(usatWin, text="6 bp repeat."),rb6)

    onDone <- function(){
        tkdestroy(usatWin)
        if(as.integer(tclvalue(rbTclVar))==0){
            usatnt <- 1
        } else {
            usatnt <- as.integer(tclvalue(rbTclVar))
        }
        Usatnts(genobject)[L] <<- usatnt
        uCount <<- length(Loci(genobject))
    }
    onBack <- function(){
        tkdestroy(usatWin)
        uCount <<- uCount + 1
        gUsatnts()
    }
    onNext <- function(){
        tkdestroy(usatWin)
        if(as.integer(tclvalue(rbTclVar))==0){
            usatnt <- 1
        } else {
            usatnt <- as.integer(tclvalue(rbTclVar))
        }
        Usatnts(genobject)[L] <<- usatnt
        uCount <<- uCount - 1
        gUsatnts()
    }
    doneBut <- tkbutton(usatWin, text=" Done ", command=onDone)
    backBut <- tkbutton(usatWin, text="<<Back", command=onBack)
    nextBut <- tkbutton(usatWin, text="Next>>", command = onNext)
    if(uCount==1) tkgrid(backBut, doneBut)
    if(uCount==length(Loci(genobject))) tkgrid(doneBut, nextBut)
    if(uCount > 1 && uCount < length(Loci(genobject)))
        tkgrid(backBut, doneBut, nextBut)
}

# Add one ploidy for all individuals
gPloidy <- function(){
    ploidyWin <- tktoplevel()
    tkwm.title(ploidyWin, "Set Ploidy")
    if(length(unique(Ploidies(genobject)))==1){
        if(is.na(unique(Ploidies(genobject)))){
            textEntryVarTcl <- tclVar(4)
        } else {
            textEntryVarTcl <- tclVar(unique(Ploidies(genobject)))
        }
    } else {
        textEntryVarTcl <- tclVar(4)
    }
    textEntryWidget <- tkentry(ploidyWin, width=2,
                               textvariable = textEntryVarTcl)
    tkgrid(tklabel(ploidyWin, text="Ploidy for entire dataset:"),
           textEntryWidget)

    onOK <- function(){
        Ploidies(genobject) <<- rep(tclvalue(textEntryVarTcl),
                                    length(Samples(genobject)))
        tkdestroy(ploidyWin)
    }
    onCancel <- function(){
        tkdestroy(ploidyWin)
    }
    OKbutton <- tkbutton(ploidyWin, text=" OK ", command=onOK)
    CancelButton <- tkbutton(ploidyWin, text=" Cancel ", command=onCancel)
    tkgrid(OKbutton, CancelButton)
}

# Run estimatePloidy
gEstimatePloidy <- function(){
    genobject <<- estimatePloidy(genobject, samples=gsamples[[csamples]],
                                 loci=gloci[[cloci]])
}

# Edit Genotypes
gEditGenotypes <- function(){
    genobject <<- editGenotypes(genobject, samples=gsamples[[csamples]],
                                loci=gloci[[cloci]])
}

importGeneMapper <- function(){
    # read file
    filename <- tclvalue(tkgetOpenFile())
    genobject <<- read.GeneMapper(filename)
    pginitialize()

    # set up window and show shat was just read
    importWin <- tktoplevel()
    tkwm.title(importWin, "Import GeneMapper File")
    tkgrid(tklabel(importWin, text=paste(filename, "read successfully.")))
    tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                              "samples,", length(Loci(genobject)), "loci.")))

    # make buttons for other options for data to add
    descriptionButton <- tkbutton(importWin, text="Add Description",
                                  command=gDescription)
    tkgrid(descriptionButton)
    popnameButton <- tkbutton(importWin, text="Add Population Names",
                              command=gPopNames)
    tkgrid(popnameButton)
    popIDbutton <- tkbutton(importWin, text="Add Population Identities",
                            command=gPopInfo)
    tkgrid(popIDbutton)
    usatntButton <- tkbutton(importWin,
                             text="Add Microsatellite Repeat Lengths",
                             command=gUsatnts)
    tkgrid(usatntButton)
    oneploidyButton <- tkbutton(importWin,
                                text="Add One Ploidy Level for All Individuals",
                                command=gPloidy)
    tkgrid(oneploidyButton)
    estimatePloidyButton <- tkbutton(importWin,
                          text="Estimate/Manually Edit Individual Ploidies",
                                     command=gEstimatePloidy)
    tkgrid(estimatePloidyButton)
    doneButton <- tkbutton(importWin, text="Done with Import",
                           command=function() tkdestroy(importWin))
    tkgrid(doneButton)
}

importStructure <- function(){
    # search for a file
    filename <- tclvalue(tkgetOpenFile())

    # get more information about the file
    strctwin <- tktoplevel()
    tkwm.title(strctwin, "Structure Import")
    tkgrab.set(strctwin)
    tkgrid(tklabel(strctwin, text=paste("Format of", filename,":")))
    # text entry for ploidy
    ploidyTcl <- tclVar(4)
    ploidyEntry <- tkentry(strctwin, width=2, textvariable=ploidyTcl)
    # text entry for missing data value
    missingTcl <- tclVar(-9)
    missingEntry <- tkentry(strctwin, width=3, textvariable=missingTcl)
    # radio buttons for tab vs. space delimited
    rbTab <- tkradiobutton(strctwin)
    rbSpc <- tkradiobutton(strctwin)
    rbDelimValue <- tclVar("\t")
    tkconfigure(rbTab, variable=rbDelimValue, value="\t")
    tkconfigure(rbSpc, variable=rbDelimValue, value=" ")
    # checkboxes for marker names and labels
    markerChk <- tkcheckbutton(strctwin)
    markerTcl <- tclVar("1")
    tkconfigure(markerChk, variable=markerTcl)
    labelChk <- tkcheckbutton(strctwin)
    labelTcl <- tclVar("1")
    tkconfigure(labelChk, variable=labelTcl)
    # text entry for extra rows
    rowsTcl <- tclVar(1)
    rowsEntry <- tkentry(strctwin, width=2, textvariable=rowsTcl)
    # indicate if and where population identities are stored
    popChk <- tkcheckbutton(strctwin) # check box for pop column present
    popTcl <- tclVar("1")
    tkconfigure(popChk, variable=popTcl)
    popColTcl <- tclVar(1) # text box to enter column number
    popEntry <- tkentry(strctwin, width=2, textvariable=popColTcl)
    # text entry for extra columns (including PopData, not including labels)
    colsTcl <- tclVar(1)
    colsEntry <- tkentry(strctwin, width=2, textvariable=colsTcl)

    # grid all of it
    tkgrid(tklabel(strctwin, text="Ploidy (rows per individual): "),ploidyEntry)
    tkgrid(tklabel(strctwin, text="Missing data symbol: "),missingEntry)
    tkgrid(tklabel(strctwin, text="Fields are separated by tabs: "),rbTab,
           tklabel(strctwin, text=" or spaces: "),rbSpc)
    tkgrid(tklabel(strctwin, text="File contains a row of marker names:"),
           markerChk,
           tklabel(strctwin, text="File contains a column of sample names:"),
           labelChk)
    tkgrid(tklabel(strctwin,
                   text="Number of extra rows, not including marker names: "),
           rowsEntry)
    tkgrid(tklabel(strctwin, text="File contains PopData:"),popChk,
           tklabel(strctwin, text="Column number of PopData (after labels):"),
           popEntry)
    tkgrid(tklabel(strctwin,
             text="Number of extra columns, including PopData but not labels:"),
           colsEntry)

    # Next and cancel buttons
    onNext <- function(){
        if(as.character(tclvalue(markerTcl))=="1") markers <- TRUE
        if(as.character(tclvalue(markerTcl))=="0") markers <- FALSE
        if(as.character(tclvalue(labelTcl))=="1") slabels <- TRUE
        if(as.character(tclvalue(labelTcl))=="0") slabels <- FALSE
        if(as.character(tclvalue(popTcl))=="0") pic <- NA
        if(as.character(tclvalue(popTcl))=="1")
            pic <- as.integer(tclvalue(popColTcl))

        genobject <<- read.Structure(filename, as.integer(tclvalue(ploidyTcl)),
                                     missingin=tclvalue(missingTcl),
                                     sep=tclvalue(rbDelimValue),
                                     markernames=markers, labels=slabels,
                                     extrarows=as.integer(tclvalue(rowsTcl)),
                                     popinfocol=pic,
                                     extracols=as.integer(tclvalue(colsTcl)))
        pginitialize()
        tkgrab.release(strctwin)
        tkdestroy(strctwin)

        # set up window for more options
        importWin <- tktoplevel()
        tkwm.title(importWin, "Structure Import")
        tkgrid(tklabel(importWin, text="File read successfully."))
        tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                                  "samples,", length(Loci(genobject)),
                                  "loci.")))
        descriptionButton <- tkbutton(importWin, text="Add Description",
                                      command=gDescription)
        tkgrid(descriptionButton)
        popnameButton <- tkbutton(importWin, text="Add Population Names",
                                  command=gPopNames)
        tkgrid(popnameButton)
        if(!all(!is.na(PopInfo(genobject)))){
            popIDbutton <- tkbutton(importWin, text="Add Population Identities",
                                    command=gPopInfo)
            tkgrid(popIDbutton)
        }
        usatntButton <- tkbutton(importWin,
                                 text="Add Microsatellite Repeat Lengths",
                                 command=gUsatnts)
        tkgrid(usatntButton)
        doneButton <- tkbutton(importWin, text="Done with Import",
                               command=function() tkdestroy(importWin))
        tkgrid(doneButton)
    }
    onCancel <- function(){
        tkgrab.release(strctwin)
        tkdestroy(strctwin)
    }
    nextBut <- tkbutton(strctwin, text="Next>>", command=onNext)
    cancelBut <- tkbutton(strctwin, text="Cancel", command=onCancel)
    tkgrid(cancelBut, nextBut)
}

importSPAGeDi <- function(){
    # get file
    filename <- tclvalue(tkgetOpenFile())

    # window to ask for allele sep
    spagWin <- tktoplevel()
    tkwm.title(spagWin, "SPAGeDi Import")
    tkgrid(tklabel(spagWin, text=paste("Format for", filename )))
    # radio buttons for allele separation options
    tkgrid(tklabel(spagWin, text="Genotype format resemles:"))
    rb1 <- tkradiobutton(spagWin)
    rb2 <- tkradiobutton(spagWin)
    rb3 <- tkradiobutton(spagWin)
    rb4 <- tkradiobutton(spagWin)
    rb5 <- tkradiobutton(spagWin)
    rb6 <- tkradiobutton(spagWin)
    rb7 <- tkradiobutton(spagWin)
    rb8 <- tkradiobutton(spagWin)
    rbvalue <- tclVar("/")
    tkconfigure(rb1, variable=rbvalue, value="")
    tkconfigure(rb2, variable=rbvalue, value="/")
    tkconfigure(rb3, variable=rbvalue, value=".")
    tkconfigure(rb4, variable=rbvalue, value=",")
    tkconfigure(rb5, variable=rbvalue, value=", ")
    tkconfigure(rb6, variable=rbvalue, value="-")
    tkconfigure(rb7, variable=rbvalue, value="--")
    tkconfigure(rb8, variable=rbvalue, value=" ")
    tkgrid(tklabel(spagWin, text="1214"),rb1)
    tkgrid(tklabel(spagWin, text="12/14"), rb2)
    tkgrid(tklabel(spagWin, text="12.14"),rb3)
    tkgrid(tklabel(spagWin, text="12,14"),rb4)
    tkgrid(tklabel(spagWin, text="12, 14"),rb5)
    tkgrid(tklabel(spagWin, text="12-14"),rb6)
    tkgrid(tklabel(spagWin, text="12--14"),rb7)
    tkgrid(tklabel(spagWin, text="12 14"),rb8)

    onNext <- function(){
        genobject <<- read.SPAGeDi(filename, allelesep=tclvalue(rbvalue))
        pginitialize()
        tkdestroy(spagWin)

        # Window with other options
        importWin <- tktoplevel()
        tkwm.title(importWin, "SPAGeDi Import")
        tkgrid(tklabel(importWin, text="File read successfully."))
        tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                                  "samples,", length(Loci(genobject)),
                                  "loci.")))
        descriptionButton <- tkbutton(importWin, text="Add Description",
                                      command=gDescription)
        tkgrid(descriptionButton)
        if(length(PopNames(genobject))==0){
            popnameButton <- tkbutton(importWin, text="Add Population Names",
                                      command=gPopNames)
            tkgrid(popnameButton)
            popIDbutton <- tkbutton(importWin, text="Add Population Identities",
                                    command=gPopInfo)
            tkgrid(popIDbutton)
        }
        usatntButton <- tkbutton(importWin,
                                 text="Add Microsatellite Repeat Lengths",
                                 command=gUsatnts)
        tkgrid(usatntButton)
        doneButton <- tkbutton(importWin, text="Done with Import",
                               command=function() tkdestroy(importWin))
        tkgrid(doneButton)
    }
    onCancel <- function(){
        tkdestroy(spagWin)
    }
    nextBut <- tkbutton(spagWin, text="Next>>", command=onNext)
    cancelBut <- tkbutton(spagWin, text="Cancel", command=onCancel)
    tkgrid(cancelBut,nextBut)
}

importGenoDive <- function(){
        # read file
    filename <- tclvalue(tkgetOpenFile())
    genobject <<- read.GenoDive(filename)
    pginitialize()

    # set up window and show shat was just read
    importWin <- tktoplevel()
    tkwm.title(importWin, "Import GenoDive File")
    tkgrid(tklabel(importWin, text=paste(filename, "read successfully.")))
    tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                              "samples,", length(Loci(genobject)), "loci.")))

    # make buttons for other options for data to add
    usatntButton <- tkbutton(importWin,
                             text="Add Microsatellite Repeat Lengths",
                             command=gUsatnts)
    tkgrid(usatntButton)
    oneploidyButton <- tkbutton(importWin,
                                text="Add One Ploidy Level for All Individuals",
                                command=gPloidy)
    tkgrid(oneploidyButton)
    estimatePloidyButton <- tkbutton(importWin,
                          text="Estimate/Manually Edit Individual Ploidies",
                                     command=gEstimatePloidy)
    tkgrid(estimatePloidyButton)
    doneButton <- tkbutton(importWin, text="Done with Import",
                           command=function() tkdestroy(importWin))
    tkgrid(doneButton)
}

importTetrasat <- function(){
        # read file
    filename <- tclvalue(tkgetOpenFile())
    genobject <<- read.Tetrasat(filename)
    pginitialize()

    # set up window and show shat was just read
    importWin <- tktoplevel()
    tkwm.title(importWin, "Import Tetrasat/Tetra File")
    tkgrid(tklabel(importWin, text=paste(filename, "read successfully.")))
    tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                              "samples,", length(Loci(genobject)), "loci.")))

    # make buttons for other options for data to add
    popnameButton <- tkbutton(importWin, text="Add Population Names",
                              command=gPopNames)
    tkgrid(popnameButton)
    usatntButton <- tkbutton(importWin,
                             text="Add Microsatellite Repeat Lengths",
                             command=gUsatnts)
    tkgrid(usatntButton)
    doneButton <- tkbutton(importWin, text="Done with Import",
                           command=function() tkdestroy(importWin))
    tkgrid(doneButton)
}

importATetra <- function(){
        # read file
    filename <- tclvalue(tkgetOpenFile())
    genobject <<- read.ATetra(filename)
    pginitialize()

    # set up window and show shat was just read
    importWin <- tktoplevel()
    tkwm.title(importWin, "Import ATetra File")
    tkgrid(tklabel(importWin, text=paste(filename, "read successfully.")))
    tkgrid(tklabel(importWin, text=paste(length(Samples(genobject)),
                              "samples,", length(Loci(genobject)), "loci.")))

    # make buttons for other options for data to add
    usatntButton <- tkbutton(importWin,
                             text="Add Microsatellite Repeat Lengths",
                             command=gUsatnts)
    tkgrid(usatntButton)
    doneButton <- tkbutton(importWin, text="Done with Import",
                           command=function() tkdestroy(importWin))
    tkgrid(doneButton)
}

polysatimport <- function(){
    importWin <- tktoplevel()
    tkwm.title(importWin, "Data Import")
    tkgrab.set(importWin)
    tkgrid(tklabel(importWin, text="Data format:"))
    rb1 <- tkradiobutton(importWin)
    rb2 <- tkradiobutton(importWin)
    rb3 <- tkradiobutton(importWin)
    rb4 <- tkradiobutton(importWin)
    rb5 <- tkradiobutton(importWin)
    rb6 <- tkradiobutton(importWin)
    rb7 <- tkradiobutton(importWin)
    rbValue <- tclVar("GeneMapper")
    tkconfigure(rb1, variable=rbValue, value="GeneMapper")
    tkconfigure(rb2, variable=rbValue, value="Structure")
    tkconfigure(rb3, variable=rbValue, value="SPAGeDi")
    tkconfigure(rb4, variable=rbValue, value="GenoDive")
    tkconfigure(rb5, variable=rbValue, value="Tetrasat")
    tkconfigure(rb6, variable=rbValue, value="ATetra")
    tkconfigure(rb7, variable=rbValue, value="binary")
    tkgrid(tklabel(importWin, text="GeneMapper "),rb1)
    tkgrid(tklabel(importWin, text="Structure "),rb2)
    tkgrid(tklabel(importWin, text="SPAGeDi "),rb3)
    tkgrid(tklabel(importWin, text="GenoDive "),rb4)
    tkgrid(tklabel(importWin, text="Tetrasat/Tetra "),rb5)
    tkgrid(tklabel(importWin, text="ATetra "),rb6)
#    tkgrid(tklabel(importWin, text="Binary presence/absence table "),rb7)

    OnCancel <- function(){
        tkgrab.release(importWin)
        tkdestroy(importWin)
    }
    OnNext <- function(){
        rbValue <- as.character(tclvalue(rbValue))
        tkgrab.release(importWin)
        tkdestroy(importWin)
        if(rbValue == "GeneMapper") importGeneMapper()
        if(rbValue == "Structure") importStructure()
        if(rbValue == "SPAGeDi") importSPAGeDi()
        if(rbValue == "GenoDive") importGenoDive()
        if(rbValue == "Tetrasat") importTetrasat()
        if(rbValue == "ATetra") importATetra()
        if(rbValue == "binary") cat("dummy")
    }
    CancelBut <- tkbutton(importWin, text="Cancel", command=OnCancel)
    NextBut <- tkbutton(importWin, text="Next>>", command=OnNext)
    tkgrid(CancelBut, NextBut)
}

polysatexport <- function(){
    exportWin <- tktoplevel()
    tkwm.title(exportWin, "Data Export")
    tkgrab.set(exportWin)
    tkgrid(tklabel(exportWin, text="Data format:"))
    rb1 <- tkradiobutton(exportWin)
    rb2 <- tkradiobutton(exportWin)
    rb3 <- tkradiobutton(exportWin)
    rb4 <- tkradiobutton(exportWin)
    rb5 <- tkradiobutton(exportWin)
    rb6 <- tkradiobutton(exportWin)
    rb7 <- tkradiobutton(exportWin)
    rbValue <- tclVar("GeneMapper")
    tkconfigure(rb1, variable=rbValue, value="GeneMapper")
    tkconfigure(rb2, variable=rbValue, value="Structure")
    tkconfigure(rb3, variable=rbValue, value="SPAGeDi")
    tkconfigure(rb4, variable=rbValue, value="GenoDive")
    tkconfigure(rb5, variable=rbValue, value="Tetrasat")
    tkconfigure(rb6, variable=rbValue, value="ATetra")
    tkconfigure(rb7, variable=rbValue, value="binary")
    tkgrid(tklabel(exportWin, text="GeneMapper "),rb1)
    tkgrid(tklabel(exportWin, text="Structure "),rb2)
    tkgrid(tklabel(exportWin, text="SPAGeDi "),rb3)
    tkgrid(tklabel(exportWin, text="GenoDive "),rb4)
    tkgrid(tklabel(exportWin, text="Tetrasat/Tetra "),rb5)
    tkgrid(tklabel(exportWin, text="ATetra "),rb6)
#    tkgrid(tklabel(exportWin, text="Binary presence/absence table "),rb7)

    OnCancel <- function(){
        tkgrab.release(exportWin)
        tkdestroy(exportWin)
    }
    OnNext <- function(){
        rbValue <- as.character(tclvalue(rbValue))
        tkgrab.release(exportWin)
        tkdestroy(exportWin)
        if(rbValue == "GeneMapper")
            write.GeneMapper(genobject,file=tclvalue(tkgetSaveFile()),
                             samples=gsamples[[csamples]],loci=gloci[[cloci]])
        if(rbValue == "Structure"){
            strpl <- tktoplevel()
            tkwm.title(strpl, "Structure Export")
            ploidyTcl <- tclVar(4)
            ploidyEntry <- tkentry(strpl, textvariable=ploidyTcl, width=3)
            tkgrid(tklabel(strpl, text="PLOIDY (rows per individual): "),
                   ploidyEntry)
            missingTcl <- tclVar(-9)
            missingEntry <- tkentry(strpl, textvariable=missingTcl, width=3)
            tkgrid(tklabel(strpl, text="Missing data symbol for file: "),
                   missingEntry)
            cancelButton <- tkbutton(strpl, text="Cancel",
                                     command=function() tkdestroy(strpl))
            okButton <- tkbutton(strpl, text="OK",command=function(){
                write.Structure(genobject, as.integer(tclvalue(ploidyTcl)),
                                file=tclvalue(tkgetSaveFile()),
                                samples=gsamples[[csamples]],
                                loci=gloci[[cloci]],
                                missingout=as.integer(tclvalue(missingTcl)))
                tkdestroy(strpl)
                })
            tkgrid(okButton, cancelButton)
        }
        if(rbValue == "SPAGeDi")
            write.SPAGeDi(genobject,file=tclvalue(tkgetSaveFile()),
                          samples=gsamples[[csamples]],loci=gloci[[cloci]])
        if(rbValue == "GenoDive")
            write.GenoDive(genobject,file=tclvalue(tkgetSaveFile()),
                          samples=gsamples[[csamples]],loci=gloci[[cloci]])
        if(rbValue == "Tetrasat")
            write.Tetrasat(genobject,file=tclvalue(tkgetSaveFile()),
                          samples=gsamples[[csamples]],loci=gloci[[cloci]])
        if(rbValue == "ATetra")
            write.ATetra(genobject,file=tclvalue(tkgetSaveFile()),
                          samples=gsamples[[csamples]],loci=gloci[[cloci]])
        if(rbValue == "binary") cat("dummy")
    }
    CancelBut <- tkbutton(exportWin, text="Cancel", command=OnCancel)
    NextBut <- tkbutton(exportWin, text="Export", command=OnNext)
    tkgrid(CancelBut, NextBut)
}

datasetscratch <- function(){
    # get sample and locus names, then make object
    slwin <- tktoplevel()
    tkgrab.set(slwin)
    tkwm.title(slwin, "Name Samples and Loci")
    tkgrid(tklabel(slwin,
                  text="Add names for all samples and loci before proceeding."))
    samframe <- data.frame(Sample.Names=c("ind1", "ind2", "ind3", "etc."),
                           stringsAsFactors=FALSE)
    locframe <- data.frame(Locus.Names=c("loc1", "loc2", "etc."),
                           stringsAsFactors=FALSE)
    addSamBut <- tkbutton(slwin, text="Add Samples", command=function(){
        samframe <<- edit(samframe)
    })
    addLocBut <- tkbutton(slwin, text="Add Loci", command=function(){
        locframe <<- edit(locframe)
    })
    doneBut <- tkbutton(slwin, text="Create Dataset", command=function(){
        # create dataset
        genobject <<- new("genambig", samples=samframe$Sample.Names,
                          loci=locframe$Locus.Names)
        pginitialize()
        tkgrab.release(slwin)
        tkdestroy(slwin)

        # make another window with options for adding everything else
        optwin <- tktoplevel()
        tkwm.title(optwin, "Add Data")
        genotypeButton <- tkbutton(optwin, text="Add Genotypes",
                                   command=function(){
                       # before editing genotypes, get max alleles
             mawin <- tktoplevel()
             tkwm.title(mawin, "Max Alleles")
             tkgrid(tklabel(mawin,
                            text="Maximum number of alleles per genotype:"))
             textEntryVarTcl <- tclVar(4)
             textEntryWidget <- tkentry(mawin, width=2,
                                        textvariable = textEntryVarTcl)
             tkgrid(textEntryWidget)
             CancelBut <- tkbutton(mawin, text="Cancel",
                                   command=function() tkdestroy(mawin))
             OkBut <- tkbutton(mawin, text=" OK ", command=function(){
                 ma <- as.integer(tclvalue(textEntryVarTcl))
                 tkdestroy(mawin)
                 genobject <<- editGenotypes(genobject, maxalleles=ma)
             })
             tkgrid(OkBut, CancelBut)
                                   })
        tkgrid(genotypeButton)
        descriptionButton <- tkbutton(optwin, text="Add Description",
                                  command=gDescription)
        tkgrid(descriptionButton)
        popnameButton <- tkbutton(optwin, text="Add Population Names",
                                  command=gPopNames)
        tkgrid(popnameButton)
        popIDbutton <- tkbutton(optwin, text="Add Population Identities",
                                command=gPopInfo)
        tkgrid(popIDbutton)
        usatntButton <- tkbutton(optwin,
                                 text="Add Microsatellite Repeat Lengths",
                                 command=gUsatnts)
        tkgrid(usatntButton)
        oneploidyButton <- tkbutton(optwin,
                               text="Add One Ploidy Level for All Individuals",
                                    command=gPloidy)
        tkgrid(oneploidyButton)
        estimatePloidyButton <- tkbutton(optwin,
                          text="Estimate/Manually Edit Individual Ploidies",
                                         command=gEstimatePloidy)
        tkgrid(estimatePloidyButton)
        doneButton <- tkbutton(optwin, text="Done with Import",
                           command=function() tkdestroy(optwin))
        tkgrid(doneButton)

    })
    tkgrid(addSamBut, addLocBut)
    tkgrid(doneBut)
}


# Add subset functions
AddSampleSubset <- function(){
    dlg <- tktoplevel()
    tkwm.deiconify(dlg)
    tkgrab.set(dlg)
    tkfocus(dlg)
    tkwm.title(dlg, "Create new sample subset")

    textEntryVarTcl <- tclVar(paste("Sample_subset_",
                                    length(gsamples), sep=""))
    textEntryWidget <- tkentry(dlg, width=20, textvariable = textEntryVarTcl)
    tkgrid(tklabel(dlg, text="Name for subset:"), textEntryWidget)

    scr <- tkscrollbar(dlg, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
    tl <- tklistbox(dlg, height=30, selectmode="extended",
                    yscrollcommand=function(...)tkset(scr,...),
                    background="white")
    tkgrid(tl, scr)
    tkgrid.configure(scr,rowspan=4,sticky="nsw")
    for(s in Samples(genobject)){
        tkinsert(tl,"end",s)
    }

    onOK <- function(){
        gsamples[[length(gsamples) + 1]] <<-
            Samples(genobject)[as.numeric(tkcurselection(tl))+1]
        names(gsamples)[length(gsamples)] <<- tclvalue(textEntryVarTcl)
        tkgrab.release(dlg)
        tkdestroy(dlg)
    }

    onCancel <- function(){
        tkgrab.release(dlg)
        tkdestroy(dlg)
    }

    Ok.but <- tkbutton(dlg, text = " OK ", command=onOK)
    Cancel.but <- tkbutton(dlg, text = " Cancel ", command=onCancel)
    tkgrid(Ok.but, Cancel.but)

    tkfocus(dlg)
    tkbind(dlg, "<Destroy>", function(){ tkgrab.release(dlg);
                                         #tkfocus(tt)
                                     })
    tkbind(textEntryWidget, "<Return>", onOK)
    tkwait.window(dlg)
}

# Add a new sample subset by population
APSampleSubset <- function(){
    dlg <- tktoplevel()
    tkwm.title(dlg, "Create a New Sample Subset")
    textEntryVarTcl <- tclVar(paste("Sample_subset_",
                                    length(gsamples), sep=""))
    textEntryWidget <- tkentry(dlg, width=20, textvariable = textEntryVarTcl)
    tkgrid(tklabel(dlg, text="Name for subset:"), textEntryWidget)

    scr <- tkscrollbar(dlg, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
    tl <- tklistbox(dlg, height=30, selectmode="extended",
                    yscrollcommand=function(...)tkset(scr,...),
                    background="white")
    tkgrid(tl, scr)
    tkgrid.configure(scr,rowspan=4,sticky="nsw")
    for(p in PopNames(genobject)){
        tkinsert(tl,"end",p)
    }

    onOK <- function(){
        gsamples[[length(gsamples) + 1]] <<-
            Samples(genobject, populations=as.numeric(tkcurselection(tl))+1)
        names(gsamples)[length(gsamples)] <<- tclvalue(textEntryVarTcl)
        tkdestroy(dlg)
    }

    onCancel <- function(){
        tkdestroy(dlg)
    }

    Ok.but <- tkbutton(dlg, text = " OK ", command=onOK)
    Cancel.but <- tkbutton(dlg, text = " Cancel ", command=onCancel)
    tkgrid(Ok.but, Cancel.but)
}

AddLocusSubset <- function(){
    dlg <- tktoplevel()
    tkwm.deiconify(dlg)
    tkgrab.set(dlg)
    tkfocus(dlg)
    tkwm.title(dlg, "Create new locus subset")

    textEntryVarTcl <- tclVar(paste("Locus_subset_",
                                    length(gloci), sep=""))
    textEntryWidget <- tkentry(dlg, width=20, textvariable = textEntryVarTcl)
    tkgrid(tklabel(dlg, text="Name for subset:"), textEntryWidget)

    scr <- tkscrollbar(dlg, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
    tl <- tklistbox(dlg, height=30, selectmode="extended",
                    yscrollcommand=function(...)tkset(scr,...),
                    background="white")
    tkgrid(tl, scr)
    tkgrid.configure(scr,rowspan=4,sticky="nsw")
    for(L in Loci(genobject)){
        tkinsert(tl,"end",L)
    }

    onOK <- function(){
        gloci[[length(gloci) + 1]] <<-
            Loci(genobject)[as.numeric(tkcurselection(tl))+1]
        names(gloci)[length(gloci)] <<- tclvalue(textEntryVarTcl)
        tkgrab.release(dlg)
        tkdestroy(dlg)
    }

    onCancel <- function(){
        tkgrab.release(dlg)
        tkdestroy(dlg)
    }

    Ok.but <- tkbutton(dlg, text = " OK ", command=onOK)
    Cancel.but <- tkbutton(dlg, text = " Cancel ", command=onCancel)
    tkgrid(Ok.but, Cancel.but)

    tkfocus(dlg)
    tkbind(dlg, "<Destroy>", function(){ tkgrab.release(dlg);
                                         #tkfocus(tt)
                                     })
    tkbind(textEntryWidget, "<Return>", onOK)
    tkwait.window(dlg)
}

viewSampleSubsets <- function(){
    sampleSubsetWindow <- tktoplevel()
    tkwm.title(sampleSubsetWindow, "View and Edit Sample Subsets")
    tkgrid(tklabel(sampleSubsetWindow, text = "Sample sets:"))
    scrSamples <- tkscrollbar(sampleSubsetWindow, command=function(...)
                              tkyview(listSamples,...))
    listSamples <- tklistbox(sampleSubsetWindow, height=10, selectmode="single",
                             yscrollcommand = function(...)
                             tkset(scrSamples,...),background="white")
    for(i in names(gsamples)){
        tkinsert(listSamples, "end", i)
    }
    tkgrid(listSamples, scrSamples)

    # Buttons along the bottom
    SampleAddButton <- tkbutton(sampleSubsetWindow, text="Add",
                                command=AddSampleSubset)
    SamplePopAddButton <- tkbutton(sampleSubsetWindow, text="Add by pop",
                                   command=APSampleSubset)
    SampleViewButton <- tkbutton(sampleSubsetWindow, text="View",
                                 command=function(){
        samview <- tktoplevel()
        tkwm.title(samview, paste("Samples in",
            names(gsamples)[as.numeric(tkcurselection(listSamples))+1]))
        samples <- gsamples[[as.numeric(tkcurselection(listSamples))+1]]
        scr <- tkscrollbar(samview, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
        tl <- tklistbox(samview, height=30, selectmode="extended",
                        yscrollcommand=function(...)tkset(scr,...),
                        background="white")
        tkgrid(tl, scr)
        tkgrid.configure(scr,rowspan=4,sticky="nsw")
        for(s in samples){
            tkinsert(tl,"end",s)
        }
    })
    SampleSelectButton <- tkbutton(sampleSubsetWindow, text="Select",
                                   command=function(){
                     # change csamples
        csamples<<-names(gsamples)[as.numeric(tkcurselection(listSamples))+1]
        tkmessageBox(title="Selection", message=paste(csamples,
           "selected.\nOnly these samples will be used in subsequent actions."),
                     icon="info", type="ok")
                                   })
    tkgrid(SampleAddButton, SamplePopAddButton, SampleViewButton,
           SampleSelectButton)
          #Also, edit, remove buttons?
    tkgrid(tklabel(sampleSubsetWindow,
                   text="Close window and reopen to refresh list."))
}

viewLocusSubsets <- function(){
    locusSubsetWindow <- tktoplevel()
    tkwm.title(locusSubsetWindow, "View and Edit Locus Subsets")
    tkgrid(tklabel(locusSubsetWindow, text = "Locus sets:"))
    scr <- tkscrollbar(locusSubsetWindow, command=function(...)
                              tkyview(lb,...))
    lb <- tklistbox(locusSubsetWindow, height=10, selectmode="single",
                             yscrollcommand = function(...)
                             tkset(scr,...),background="white")
    for(i in names(gloci)){
        tkinsert(lb, "end", i)
    }
    tkgrid(lb, scr)

    # Buttons along the bottom
    LocusAddButton <- tkbutton(locusSubsetWindow, text="Add",
                                command=AddLocusSubset)
    LocusViewButton <- tkbutton(locusSubsetWindow, text="View",
                                 command=function(){
        locview <- tktoplevel()
        tkwm.title(locview, paste("Loci in",
            names(gloci)[as.numeric(tkcurselection(lb))+1]))
        loci <- gloci[[as.numeric(tkcurselection(lb))+1]]
        scrV <- tkscrollbar(locview, repeatinterval=5, command=function(...)
                       tkyview(tl,...))
        tl <- tklistbox(locview, height=30, selectmode="extended",
                        yscrollcommand=function(...)tkset(scrV,...),
                        background="white")
        tkgrid(tl, scrV)
        tkgrid.configure(scr,rowspan=4,sticky="nsw")
        for(L in loci){
            tkinsert(tl,"end",L)
        }
    })
    LocusSelectButton <- tkbutton(locusSubsetWindow, text="Select",
                                   command=function(){
                     # change cloci
        cloci<<-names(gloci)[as.numeric(tkcurselection(lb))+1]
        tkmessageBox(title="Selection", message=paste(cloci,
           "selected.\nOnly these loci will be used in subsequent actions."),
                     icon="info", type="ok")
                                   })
    tkgrid(LocusAddButton, LocusViewButton,
           LocusSelectButton)
          #Also, edit, remove buttons?
    tkgrid(tklabel(locusSubsetWindow,
                   text="Close window and reopen to refresh list."))
}

# Main GUI window
launchMain <- function(){
    tt <- tktoplevel()
    tkwm.title(tt, "Polysat Main Window")
    topMenu <- tkmenu(tt)
    tkconfigure(tt, menu=topMenu)

    # Set up menus
    fileMenu <- tkmenu(topMenu, tearoff=FALSE)
    tkadd(fileMenu, "command", label = "Import data", command = polysatimport)
    tkadd(fileMenu, "command", label = "Export data", command = polysatexport)
    tkadd(fileMenu, "command", label = "New dataset from scratch",
          command = datasetscratch)
    tkadd(fileMenu, "command", label = "Save project", command = function(){
        save(list = ls(1)[ls(1) %in% c("genobject", "gsamples", "gloci")],
             file=tclvalue(tkgetSaveFile()))
        # find an option to add .RData extension
    })
    tkadd(fileMenu, "command", label = "Load project", command = function(){
        load(tclvalue(tkgetOpenFile()))
    })
    tkadd(fileMenu, "command", label = "Quit", command = function()
          tkdestroy(tt))
    tkadd(topMenu, "cascade", label = "File", menu = fileMenu)

    viewMenu <- tkmenu(topMenu, tearoff=FALSE)
    tkadd(viewMenu, "command", label = "Summary (printed to console)",
          command = function() summary(genobject[gsamples[[csamples]],
          gloci[[cloci]]]))
    tkadd(viewMenu, "command", label="Genotypes (printed to console)",
          command=function() viewGenotypes(genobject, gsamples[[csamples]],
          gloci[[cloci]]))
    tkadd(topMenu, "cascade", label = "View", menu=viewMenu)

    editMenu <- tkmenu(topMenu, tearoff=FALSE)
    tkadd(editMenu, "command", label = "Description", command=gDescription)
    tkadd(editMenu, "command", label = "Population Names", command=gPopNames)
    tkadd(editMenu, "command", label = "Population Identities",
          command = gPopInfo)
    tkadd(editMenu, "command", label = "Repeat Lengths", command=gUsatnts)
    tkadd(editMenu, "command", label = "Ploidy (entire dataset)",
          command=gPloidy)
    tkadd(editMenu, "command", label = "Ploidy (by sample)",
          command=gEstimatePloidy)
    tkadd(editMenu, "command", label = "Genotypes", command=gEditGenotypes)
    tkadd(topMenu, "cascade", label = "Edit", menu = editMenu)

    analyzeMenu <- tkmenu(topMenu, tearoff=FALSE)
    tkadd(topMenu, "cascade", label = "Analyze", menu = analyzeMenu)

    ## Buttons
    samSubsetButton <- tkbutton(tt, text="View/Edit Sample Subsets",
                                command=viewSampleSubsets)
    locSubsetButton <- tkbutton(tt, text="View/Edit Locus Subsets",
                                command=viewLocusSubsets)
    tkgrid(samSubsetButton)
    tkgrid(locSubsetButton)
}

####################
# Opening dialog box - import, load, or use current data set?
openingDlg <- tktoplevel()
tkwm.title(openingDlg, "Choose or Create a Dataset")
if(!identical(genobject,new("genambig"))){
    tkgrid(tklabel(openingDlg, text=paste("Current dataset:",
                               Description(genobject))))
    tkgrid(tklabel(openingDlg, text=paste(length(Samples(genobject)), "samples",
                               length(Loci(genobject)), "loci.")))
    useCurrentButton <- tkbutton(openingDlg, text="Use Current Dataset",
                                 command = function(){
                                     tkdestroy(openingDlg)
                                     launchMain()})
    tkgrid(useCurrentButton)
}
importButton <- tkbutton(openingDlg, text="Import from Text File",
                         command = function(){
                             launchMain()
                             polysatimport()
                         tkdestroy(openingDlg)})
tkgrid(importButton)
loadButton <- tkbutton(openingDlg, text="Load Previous Project",
                       command = function(){
                           load(tclvalue(tkgetOpenFile()))
                           tkdestroy(openingDlg)
                           launchMain()})
tkgrid(loadButton)
scratchButton <- tkbutton(openingDlg, text="Build Dataset from Scratch",
                          command=function(){
                              launchMain()
                              datasetscratch()
                              tkdestroy(openingDlg)})
tkgrid(scratchButton)
